{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "tough-angola",
   "metadata": {},
   "source": [
    "# 基本数据类型的拷贝遍历和迭代"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "urban-extraction",
   "metadata": {},
   "source": [
    "---\n",
    "## 直接赋值、浅拷贝和深拷贝  \n",
    "* 直接赋值：其实就是对象的引用（别名）。\n",
    "* 浅拷贝(copy)：拷贝父对象，不会拷贝对象的内部的子对象。\n",
    "* 深拷贝(deepcopy)： copy 模块的 deepcopy 方法，完全拷贝了父对象及其子对象。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "possible-arcade",
   "metadata": {},
   "outputs": [],
   "source": [
    "#引用\n",
    "a = [1,[1,2,3]]\n",
    "b = a\n",
    "b.append(0)\n",
    "b[1].append(0)\n",
    "print(a,'\\n',b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fitting-round",
   "metadata": {},
   "outputs": [],
   "source": [
    "#浅拷贝\n",
    "import copy\n",
    "a = [1,[1,2,3]]\n",
    "b = copy.copy(a) #a.copy()也行\n",
    "b.append(0)\n",
    "b[1].append(0)\n",
    "print(a,'\\n',b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "institutional-endorsement",
   "metadata": {},
   "outputs": [],
   "source": [
    "#深拷贝\n",
    "a = [1,[1,2,3]]\n",
    "b = copy.deepcopy(a)\n",
    "b.append(0)\n",
    "b[1].append(0)\n",
    "print(a,'\\n',b)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "saving-pressure",
   "metadata": {},
   "source": [
    "---\n",
    "## 数据类型转换"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "thousand-relief",
   "metadata": {},
   "outputs": [],
   "source": [
    "num=5.4\n",
    "print(\"int转换为一个整数:\",int(num))\n",
    "print(\"float转换为一个浮点数:\",float(int(num)))\n",
    "print(\"complex创建一个复数:\",complex(num,num))\n",
    "print(\"str转换为字符串:\",str(num))\n",
    "print(\"repr转换为表达式字符串:\",repr(num))\n",
    "string=\"num**2\"\n",
    "print(\"eval计算在字符串中的有效Python表达式,并返回一个对象:\",eval(string))\n",
    "names=[\"xiaoming\",\"xiaohong\",\"xiaolan\"]\n",
    "print(\"tuple转换为一个元组:\",tuple(names))\n",
    "names=(\"xiaoming\",\"xiaohong\",\"xiaolan\")\n",
    "print(\"list转换为一个列表:\",list(names))\n",
    "print(\"set转换为可变集合:\",set(names))\n",
    "print(\"frozenset转换为不可变集合:\",frozenset(names))\n",
    "names=((\"xiaoming\",1),(\"xiaohong\",2),(\"xiaolan\",3))\n",
    "print(\"dict创建一个字典,必须是一个 (key, value)元组序列:\",dict(names))\n",
    "print(\"chr将一个整数转换为一个字符:\",chr(97))\n",
    "print(\"ord将一个字符转换为它的整数值:\",ord('a'))\n",
    "print(\"hex将一个整数转换为一个十六进制字符串:\",hex(15))\n",
    "print(\"oct将一个整数转换为一个八进制字符串:\",oct(15))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "powered-amsterdam",
   "metadata": {},
   "source": [
    "---\n",
    "## 推导式"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "amber-reservation",
   "metadata": {},
   "source": [
    "1. 列表推导式  \n",
    "**`[表达式 for 变量 in 列表 if 条件]`**  \n",
    "* 表达式：列表生成元素表达式，可以是有返回值的函数。  \n",
    "* for 变量 in 列表：迭代 列表 将 变量 传入到 表达式 表达式中。  \n",
    "* if 条件：条件语句，可以过滤列表中不符合条件的值。  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "breathing-address",
   "metadata": {},
   "outputs": [],
   "source": [
    "names = ['Bob','Tom','alice','Jerry','Wendy','Smith']\n",
    "new_names = [name.upper()for name in names if len(name)>3]\n",
    "print(new_names)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "several-lover",
   "metadata": {},
   "source": [
    "2. 字典推导式  \n",
    "**`{key表达式:value表达式 for 变量 in 列表 if 条件}`**  \n",
    "* key表达式:value表达式：生成键值对\n",
    "* for 变量 in 列表：迭代 列表 将 变量 传入到 key表达式:value表达式 中。  \n",
    "* if 条件：条件语句，可以过滤列表中不符合条件的值。  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "engaged-consistency",
   "metadata": {},
   "outputs": [],
   "source": [
    "names = ['Bob','Tom','alice','Jerry','Wendy','Smith']\n",
    "new_names = {name:len(name) for name in names if len(name)>3}\n",
    "print(new_names)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "powerful-london",
   "metadata": {},
   "source": [
    "3. 集合推导式\n",
    "**`{表达式 for 变量 in 列表 if 条件}`**  \n",
    "* 表达式：列表生成元素表达式，可以是有返回值的函数。  \n",
    "* for 变量 in 列表：迭代 列表 将 变量 传入到 表达式 表达式中。  \n",
    "* if 条件：条件语句，可以过滤列表中不符合条件的值。 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "spiritual-contribution",
   "metadata": {},
   "outputs": [],
   "source": [
    "names = ['Bob','Tom','alice','Jerry','Wendy','Smith']\n",
    "new_names = {name for name in names if len(name)>3}\n",
    "print(new_names)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "homeless-carolina",
   "metadata": {},
   "source": [
    "4. 元组推导式\n",
    "**`（表达式 for 变量 in 列表 if 条件）`**  \n",
    "* 表达式：列表生成元素表达式，可以是有返回值的函数。  \n",
    "* for 变量 in 列表：迭代 列表 将 变量 传入到 表达式 表达式中。  \n",
    "* if 条件：条件语句，可以过滤列表中不符合条件的值。\n",
    "\n",
    "* 返回对象是个生成器，使用tuple()即可转化为元组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eligible-parks",
   "metadata": {},
   "outputs": [],
   "source": [
    "names = ['Bob','Tom','alice','Jerry','Wendy','Smith']\n",
    "new_names = (name for name in names if len(name)>3)\n",
    "print(new_names)\n",
    "print(tuple(new_names))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "higher-alfred",
   "metadata": {},
   "source": [
    "5. 使用range()快速创建  \n",
    "range()返回的是可迭代对象，并不是某一具体数据类型，使用迭代器生成相应数据类型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "graduate-maria",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(range(1,10,2))\n",
    "print(list(range(1,10,2)))\n",
    "print(set(range(1,10,2)))\n",
    "print(tuple(range(1,10,2)),'\\n')\n",
    "print(\"找出1-50的所有非3倍数的单数-列表、集合、元组\")\n",
    "print([x for x in range(1,50,2) if x%3])\n",
    "print({x for x in range(1,50,2) if x%3})\n",
    "print(tuple(x for x in range(1,50,2) if x%3))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "prompt-basket",
   "metadata": {},
   "source": [
    "---\n",
    "## 迭代器  \n",
    "* 迭代器对象从集合的第一个元素开始访问，直到所有的元素被访问完结束。迭代器只能往前不会后退  \n",
    "* 两个基本的方法：iter() 和 next()  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "indie-shape",
   "metadata": {},
   "outputs": [],
   "source": [
    "list=[1,2,3,4]\n",
    "it = iter(list)\n",
    "print(next(it))\n",
    "print(next(it))\n",
    "print(next(it))\n",
    "print(next(it))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "illegal-morning",
   "metadata": {},
   "outputs": [],
   "source": [
    "# StopIteration 异常用于标识迭代的完成，防止出现无限循环的情况，在 __next__() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代\n",
    "class MyNumbers:\n",
    "  def __iter__(self):\n",
    "    self.a = 1\n",
    "    return self\n",
    " \n",
    "  def __next__(self):\n",
    "    if self.a <= 20:\n",
    "      x = self.a\n",
    "      self.a += 1\n",
    "      return x\n",
    "    else:\n",
    "      raise StopIteration\n",
    " \n",
    "myclass = MyNumbers()\n",
    "myiter = iter(myclass)\n",
    " \n",
    "for x in myiter:\n",
    "  print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "occupational-retrieval",
   "metadata": {},
   "source": [
    "---\n",
    "## 生成器\n",
    "* 使用了 yield 的函数被称为生成器（generator）  \n",
    "* 生成器是一个返回迭代器的函数，只能用于迭代操作，更简单点理解生成器就是一个迭代器\n",
    "* 在调用生成器运行的过程中，每次遇到 yield 时函数会暂停并保存当前所有的运行信息，返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "blond-discussion",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 13 21 34 55 "
     ]
    }
   ],
   "source": [
    "def fibonacci(n): # 生成器函数 - 斐波那契\n",
    "    a, b, counter = 0, 1, 0\n",
    "    while True:\n",
    "        if (counter >= n): \n",
    "            return\n",
    "        yield a\n",
    "        a, b = b, a + b\n",
    "        counter += 1\n",
    "f = fibonacci(11) # f 是一个迭代器，由生成器返回生成\n",
    "\n",
    "for i in f:\n",
    "    print (i, end=\" \")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "electrical-upgrade",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "((0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter'))\n"
     ]
    }
   ],
   "source": [
    "seasons = ['Spring', 'Summer', 'Fall', 'Winter']\n",
    "print(tuple(enumerate(seasons)))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "suburban-reception",
   "metadata": {},
   "source": [
    "---\n",
    "## 作用域\n",
    "* 有四种作用域：\n",
    "    * L（Local）：最内层，包含局部变量，比如一个函数/方法内部。\n",
    "    * E（Enclosing）：包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数，一个函数（或类） A 里面又包含了一个函数 B ，那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。\n",
    "    * G（Global）：当前脚本的最外层，比如当前模块的全局变量。\n",
    "    * B（Built-in）： 包含了内建的变量/关键字等，最后被搜索。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "impaired-tulsa",
   "metadata": {},
   "source": [
    "#### global关键字\n",
    "内部作用域想修改外部全局作用域的变量时"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "differential-grill",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "100\n",
      "10\n",
      "100\n"
     ]
    }
   ],
   "source": [
    "num = 1\n",
    "def outer():\n",
    "    num = 10\n",
    "    def inner():\n",
    "        global num   # nonlocal关键字声明\n",
    "        num = 100\n",
    "        print(num)\n",
    "    inner()\n",
    "    print(num)\n",
    "outer()\n",
    "print(num)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "working-witness",
   "metadata": {},
   "source": [
    "#### nonlocal 关键字\n",
    "如果要修改嵌套作用域（enclosing 作用域，外层非全局作用域）中的变量则需要 nonlocal 关键字"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "egyptian-emphasis",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "100\n",
      "100\n",
      "1\n"
     ]
    }
   ],
   "source": [
    "num = 1\n",
    "def outer():\n",
    "    num = 10\n",
    "    def inner():\n",
    "        nonlocal num   # nonlocal关键字声明\n",
    "        num = 100\n",
    "        print(num)\n",
    "    inner()\n",
    "    print(num)\n",
    "outer()\n",
    "print(num)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python[conda env:torch38]",
   "language": "python",
   "name": "torch38"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
